gusucode.com > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序 > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序/code/Explorer/CJFlatSplitterWnd.cpp
// CJFlatSplitterWnd.cpp : implementation file // Copyright ? 1998-1999 CodeJock.com, All Rights Reserved. // See ReadMe.txt for TERMS OF USE. // // Based on the CSplitterWndEx class written by Oleg G. Galkin. // mailto:OlegGa@vest.msk.ru // http://www.codeguru.com/splitter/show_hide_static_panes.shtml // ///////////////////////////////////////////////////////////////////////////// /**************************************************************************** * * $Date: 10/14/99 9:25p $ * $Revision: 6 $ * $Archive: /CodeJock/CJLibrary/CJFlatSplitterWnd.cpp $ * * $History: CJFlatSplitterWnd.cpp $ * * ***************** Version 6 ***************** * User: Kirk Stowell Date: 10/14/99 Time: 9:25p * Updated in $/CodeJock/CJLibrary * Fixed bug with hiding or showing panes where the incorrect splitter * control id was used. * * ***************** Version 5 ***************** * User: Kirk Stowell Date: 9/13/99 Time: 5:44a * Updated in $/CodeJockey/CJLibrary * Fixed assertion when using ReplaceView to display a CFormView derived * class in a debug build - Tom * * ***************** Version 4 ***************** * User: Kirk Stowell Date: 9/13/99 Time: 5:40a * Updated in $/CodeJockey/CJLibrary * Fixed bug with GetPane() call in ShowRow() where row and col arguments * were switched. - Francis * * ***************** Version 3 ***************** * User: Kirk Stowell Date: 8/31/99 Time: 1:11a * Updated in $/CodeJockey/CJLibrary * Updated copyright and contact information. * * ***************** Version 2 ***************** * User: Kirk Stowell Date: 7/25/99 Time: 12:30a * Updated in $/CodeJockey/CJLibrary * * ***************** Version 1 ***************** * User: Kirk Stowell Date: 7/14/99 Time: 10:00p * Created in $/CodeJockey/CJLibrary * Class added to support flat splitters, removable splitter views and * view manipulation. * ***************************************************************************/ ///////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "CJFlatSplitterWnd.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CCJFlatSplitterWnd CCJFlatSplitterWnd::CCJFlatSplitterWnd() { m_bFlatSplitter = TRUE; m_nHiddenCol = -1; m_nHiddenRow = -1; } CCJFlatSplitterWnd::~CCJFlatSplitterWnd() { } BEGIN_MESSAGE_MAP(CCJFlatSplitterWnd, CSplitterWnd) //{{AFX_MSG_MAP(CCJFlatSplitterWnd) ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CCJFlatSplitterWnd message handlers void CCJFlatSplitterWnd::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg) { if( m_bFlatSplitter ) { // if pDC == NULL, then just invalidate if (pDC == NULL) { RedrawWindow(rectArg, NULL, RDW_INVALIDATE|RDW_NOCHILDREN); return; } ASSERT_VALID(pDC); // otherwise, actually draw CRect rect = rectArg; switch (nType) { case splitBorder: ASSERT(afxData.bWin4); pDC->Draw3dRect(rect, afxData.clrBtnFace, afxData.clrBtnFace); rect.InflateRect(-CX_BORDER, -CY_BORDER); pDC->Draw3dRect(rect, afxData.clrBtnShadow, afxData.clrBtnHilite); return; case splitIntersection: ASSERT(!afxData.bWin4); break; case splitBox: if (afxData.bWin4) { pDC->Draw3dRect(rect, afxData.clrBtnFace, afxData.clrWindowFrame); rect.InflateRect(-CX_BORDER, -CY_BORDER); pDC->Draw3dRect(rect, afxData.clrBtnHilite, afxData.clrBtnShadow); rect.InflateRect(-CX_BORDER, -CY_BORDER); break; } // fall through... case splitBar: if (!afxData.bWin4) { pDC->Draw3dRect(rect, afxData.clrBtnHilite, afxData.clrBtnShadow); rect.InflateRect(-CX_BORDER, -CY_BORDER); } break; default: ASSERT(FALSE); // unknown splitter type } // fill the middle pDC->FillSolidRect(rect, afxData.clrBtnFace); } else { CSplitterWnd::OnDrawSplitter(pDC, nType, rectArg); } } void CCJFlatSplitterWnd::OnPaint() { if( m_bFlatSplitter ) { ASSERT_VALID(this); CPaintDC dc(this); CRect rectClient; GetClientRect(&rectClient); CRect rectInside; GetInsideRect(rectInside); rectInside.InflateRect(4,4); // draw the splitter boxes if (m_bHasVScroll && m_nRows < m_nMaxRows) { OnDrawSplitter(&dc, splitBox, CRect(rectInside.right, rectClient.top, rectClient.right, rectClient.top + m_cySplitter)); } if (m_bHasHScroll && m_nCols < m_nMaxCols) { OnDrawSplitter(&dc, splitBox, CRect(rectClient.left, rectInside.bottom, rectClient.left + m_cxSplitter, rectClient.bottom)); } // extend split bars to window border (past margins) DrawAllSplitBars(&dc, rectInside.right, rectInside.bottom); // draw splitter intersections (inside only) GetInsideRect(rectInside); dc.IntersectClipRect(rectInside); CRect rect; rect.top = rectInside.top; for (int row = 0; row < m_nRows - 1; row++) { rect.top += m_pRowInfo[row].nCurSize + m_cyBorderShare; rect.bottom = rect.top + m_cySplitter; rect.left = rectInside.left; for (int col = 0; col < m_nCols - 1; col++) { rect.left += m_pColInfo[col].nCurSize + m_cxBorderShare; rect.right = rect.left + m_cxSplitter; OnDrawSplitter(&dc, splitIntersection, rect); rect.left = rect.right + m_cxBorderShare; } rect.top = rect.bottom + m_cxBorderShare; } } else { CSplitterWnd::OnPaint(); } } void CCJFlatSplitterWnd::HideRow(int nRowHide) { ASSERT_VALID( this ); ASSERT( m_nRows > 1 ); ASSERT( nRowHide < m_nRows ); ASSERT( m_nHiddenRow == -1 ); m_nHiddenRow = nRowHide; int nActiveRow, nActiveCol; // if the nRow has an active window -- change it if( GetActivePane( &nActiveRow, &nActiveCol ) != NULL ) { if( nActiveRow == nRowHide ) { if( ++nActiveRow >= m_nRows ) nActiveRow = 0; SetActivePane( nActiveRow, nActiveCol ); } } // hide all nRow panes. for( int nCol = 0; nCol < m_nCols; ++nCol ) { CWnd* pPaneHide = GetPane( nRowHide, nCol ); ASSERT( pPaneHide != NULL ); pPaneHide->ShowWindow( SW_HIDE ); pPaneHide->SetDlgCtrlID( AFX_IDW_PANE_FIRST+nCol + 16*m_nRows ); for( int nRow = nRowHide+1; nRow < m_nRows; ++nRow ) { CWnd* pPane = GetPane( nRow, nCol ); ASSERT( pPane != NULL ); pPane->SetDlgCtrlID( IdFromRowCol( nRow-1, nCol )); } } m_nRows--; m_pRowInfo[m_nRows].nCurSize = m_pRowInfo[nRowHide].nCurSize; RecalcLayout(); } void CCJFlatSplitterWnd::ShowRow() { ASSERT_VALID( this ); ASSERT( m_nRows < m_nMaxRows ); ASSERT( m_nHiddenRow != -1 ); int nShowRow = m_nHiddenRow; m_nHiddenRow = -1; int cyNew = m_pRowInfo[m_nRows].nCurSize; m_nRows++; // add a nRow ASSERT( m_nRows == m_nMaxRows ); int nRow; // Show the hidden nRow for( int nCol = 0; nCol < m_nCols; ++nCol ) { CWnd* pPaneShow = GetDlgItem( AFX_IDW_PANE_FIRST+nCol + 16*m_nRows ); ASSERT( pPaneShow != NULL ); pPaneShow->ShowWindow( SW_SHOWNA ); for( nRow = m_nRows - 2; nRow >= nShowRow; --nRow ) { CWnd* pPane = GetPane( nRow, nCol ); ASSERT( pPane != NULL ); pPane->SetDlgCtrlID( IdFromRowCol( nRow + 1, nCol )); } pPaneShow->SetDlgCtrlID( IdFromRowCol( nShowRow, nCol )); } // new panes have been created -- recalculate layout for( nRow = nShowRow+1; nRow < m_nRows; nRow++ ) m_pRowInfo[nRow].nIdealSize = m_pRowInfo[nRow - 1].nCurSize; m_pRowInfo[nShowRow].nIdealSize = cyNew; RecalcLayout(); } void CCJFlatSplitterWnd::HideColumn(int nColHide) { ASSERT_VALID( this ); ASSERT( m_nCols > 1 ); ASSERT( nColHide < m_nCols ); ASSERT( m_nHiddenCol == -1 ); m_nHiddenCol = nColHide; // if the column has an active window -- change it int nActiveRow, nActiveCol; if( GetActivePane( &nActiveRow, &nActiveCol ) != NULL ) { if( nActiveCol == nColHide ) { if( ++nActiveCol >= m_nCols ) nActiveCol = 0; SetActivePane( nActiveRow, nActiveCol ); } } // hide all column panes for( int nRow = 0; nRow < m_nRows; nRow++) { CWnd* pPaneHide = GetPane(nRow, nColHide); ASSERT( pPaneHide != NULL ); pPaneHide->ShowWindow(SW_HIDE); pPaneHide->SetDlgCtrlID( AFX_IDW_PANE_FIRST+m_nCols + 16*nRow ); for( int nCol = nColHide + 1; nCol < m_nCols; nCol++ ) { CWnd* pPane = GetPane( nRow, nCol ); ASSERT( pPane != NULL ); pPane->SetDlgCtrlID( IdFromRowCol( nRow, nCol - 1 )); } } m_nCols--; m_pColInfo[m_nCols].nCurSize = m_pColInfo[nColHide].nCurSize; RecalcLayout(); } void CCJFlatSplitterWnd::ShowColumn() { ASSERT_VALID( this ); ASSERT( m_nCols < m_nMaxCols ); ASSERT( m_nHiddenCol != -1 ); int nShowCol = m_nHiddenCol; m_nHiddenCol = -1; int cxNew = m_pColInfo[m_nCols].nCurSize; m_nCols++; // add a column ASSERT( m_nCols == m_nMaxCols ); int nCol; // Show the hidden column for( int nRow = 0; nRow < m_nRows; ++nRow ) { CWnd* pPaneShow = GetDlgItem( AFX_IDW_PANE_FIRST+m_nCols + 16*nRow ); ASSERT( pPaneShow != NULL ); pPaneShow->ShowWindow( SW_SHOWNA ); for( nCol = m_nCols - 2; nCol >= nShowCol; --nCol ) { CWnd* pPane = GetPane( nRow, nCol ); ASSERT( pPane != NULL ); pPane->SetDlgCtrlID( IdFromRowCol( nRow, nCol + 1 )); } pPaneShow->SetDlgCtrlID( IdFromRowCol( nRow, nShowCol )); } // new panes have been created -- recalculate layout for( nCol = nShowCol+1; nCol < m_nCols; nCol++ ) m_pColInfo[nCol].nIdealSize = m_pColInfo[nCol - 1].nCurSize; m_pColInfo[nShowCol].nIdealSize = cxNew; RecalcLayout(); } BOOL CCJFlatSplitterWnd::ReplaceView(int nRow, int nCol, CRuntimeClass *pViewClass) { CView *pView = DYNAMIC_DOWNCAST( CView, GetPane( nRow, nCol )); ASSERT_KINDOF( CView, pView ); if( pView->IsKindOf( pViewClass )) return FALSE; // Get pointer to CDocument object so that it can be used in the creation // process of the new view CDocument *pDoc = pView->GetDocument(); int nID = pView->GetDlgCtrlID(); int nWidth, nHeight, nMinWidth, nMinHeight; GetRowInfo( nRow, nWidth, nMinWidth ); GetColumnInfo( nCol, nHeight, nMinHeight ); // Delete existing view DeleteView(nRow, nCol); // Create new view CCreateContext context; context.m_pCurrentDoc = pDoc; CreateView( nRow, nCol, pViewClass, CSize( nWidth, nHeight ), &context ); pView = DYNAMIC_DOWNCAST( CView, GetPane( nRow, nCol )); ASSERT_KINDOF( CView, pView ); pView->SetDlgCtrlID( nID ); SetRowInfo( nRow, nWidth, nMinWidth ); SetColumnInfo( nCol, nHeight, nMinHeight ); RecalcLayout(); return TRUE; } BOOL CCJFlatSplitterWnd::SwitchView(int nRow, int nCol, CView *pNewView) { CView *pOldView = DYNAMIC_DOWNCAST( CView, GetPane( nRow, nCol )); ASSERT_KINDOF( CView, pOldView ); if( pOldView == pNewView ) return FALSE; int nOldID, nNewID; nOldID = pOldView->GetDlgCtrlID(); nNewID = pNewView->GetDlgCtrlID(); pOldView->ShowWindow(SW_HIDE); pNewView->ShowWindow(SW_SHOW); pOldView->SetDlgCtrlID(nNewID); pNewView->SetDlgCtrlID(nOldID); RecalcLayout(); return TRUE; }